package main

import (
	"fmt"
	"sync"
	"time"
)

// GO语言的并发模型有三个：
// 1. 并发（Concurrency）：允许多个任务同时运行，每个任务都有自己的执行栈和局部变量。
// 2. 并行（Parallelism）：允许多个任务同时运行，但共享内存。
// 3. 异步（Asynchronous）：允许多个任务同时运行，但任务之间没有依赖关系，任务的执行结果没有先后顺序。

// GO语言的并发机制是通过 goroutine 和 channel 来实现的。
// goroutine 是轻量级线程，可以与其他 goroutine 并发执行。
// channel 是用于两个 goroutine 之间通信的管道。

// GO启动时会自动创建主goroutine，主goroutine负责调度其他goroutine，并管理其生命周期。
// 启动协程很简单，只需在函数前面加上关键字go即可。
// 例如：
// go func() {
//     // do something
// }()

func worker()  {
	for i := 0; i < 5; i++{
		time.Sleep(time.Second * 1)
		fmt.Println("worker:", i)
	}
}

// 通道（Channel）
// 通道是用于两个 goroutine 之间通信的管道。
// 定义语法
// var ch  = make(chan int)
// 向通道发送数据
// ch <- 1
// 从通道接收数据
// v := <-ch
// func main() {
// 	go worker()
// 	for i := 0; i < 5; i++{
// 		time.Sleep(time.Second * 1)
// 		fmt.Println("main:", i)
// 	}
// }

// 使用WaitGroup来等待协程结束
// 定义语法
// var wg sync.WaitGroup
// wg.Add(1)
// go func() {
//     // do something
//     wg.Done()
// }()
// wg.Wait()
// 注意：WaitGroup只能用于协程，不能用于线程。

var wg sync.WaitGroup

func worker2()  {
	defer wg.Done()
	for i := 0; i < 5; i++{
		time.Sleep(time.Second * 1)
		fmt.Println("worker2:", i)
	}
}

func main() {
	wg.Add(1)
	go worker2()
	println("main start")
	wg.Wait()
	println("main end")
}